module soc (
    input clk,
    input rst
);
  logic    o_iram_ready;
  logic    o_iram_valid;
  IRAM_Req o_iram_req;
  IRAM_Rsp i_iram_rsp;
  //Memory Req Port
  logic    o_mem_req_valid;
  MEM_REQ  o_mem_req;
  logic    o_mem_req_ready;
  logic    o_mem_req_kill_prev;
  logic    i_mem_early_wakeup_valid;
  PRF_IDX  i_mem_early_wakeup_prf_idx;
  //Memory Rsp Port
  logic    i_mem_rsp_valid;
  MEM_RSP  i_mem_rsp;
  logic    i_mem_rsp_ready;

  logic biu_i_req_ready;
  logic dtcm_i_req_ready;

  logic    dtcm_mem_rsp_valid;
  MEM_RSP  dtcm_mem_rsp;
  logic    dtcm_mem_rsp_ready;

  logic    biu_mem_rsp_valid;
  MEM_RSP  biu_mem_rsp;
  logic    biu_mem_rsp_ready;

  mcore inst_mcore (.*);

  assign o_mem_req_ready = biu_i_req_ready & dtcm_i_req_ready;
  logic   arbiter_i_valid[1:0];
  logic   arbiter_i_ready[1:0];
  MEM_RSP arbiter_i_data [1:0];

  assign arbiter_i_valid[0] = dtcm_mem_rsp_valid;
  assign arbiter_i_data[0] = dtcm_mem_rsp;
  assign dtcm_mem_rsp_ready = arbiter_i_ready[0];

  assign arbiter_i_valid[1] = biu_mem_rsp_valid;
  assign arbiter_i_data[1] = biu_mem_rsp;
  assign biu_mem_rsp_ready = arbiter_i_ready[1];

  localparam MEM_RSP_SIZE = $size(MEM_RSP);
  arbiter #(MEM_RSP_SIZE, 2) mem_rsp_arbiter (
    .i_valid(arbiter_i_valid),
    .i_data (arbiter_i_data),
    .i_ready(arbiter_i_ready),
    .o_valid(i_mem_rsp_valid),
    .o_data (i_mem_rsp),
    .o_ready(i_mem_rsp_ready)
  );

  dtcm inst_dtcm (
    .req_valid(o_mem_req_valid & (o_mem_req.addr[31:28] == 'h8) & biu_i_req_ready),
    .req(o_mem_req),
    .req_ready(dtcm_i_req_ready),
    .req_kill_prev(o_mem_req_kill_prev),
    .early_wakeup_valid(i_mem_early_wakeup_valid),
    .early_wakeup_prf_idx(i_mem_early_wakeup_prf_idx),
    .rsp_valid(dtcm_mem_rsp_valid),
    .rsp(dtcm_mem_rsp),
    .rsp_ready(dtcm_mem_rsp_ready),
    .*
  );

  logic         axi_awready;
  logic         axi_awvalid;
  logic [31:0]  axi_awaddr;
  // logic [ 2:0] axi_awsize;
  logic         axi_wready;
  logic         axi_wvalid;
  logic [63:0]  axi_wdata;
  logic         axi_bready;
  logic         axi_bvalid;
  logic         axi_arready;
  logic         axi_arvalid;
  logic [31:0]  axi_araddr;
  // logic [ 2:0] axi_arsize;
  logic         axi_rready;
  logic         axi_rvalid;
  logic  [63:0] axi_rdata;

  biu inst_biu (
    .req_valid(o_mem_req_valid & (o_mem_req.addr[31:28] != 'h8) & dtcm_i_req_ready),
    .req(o_mem_req),
    .req_ready(biu_i_req_ready),
    .rsp_valid(biu_mem_rsp_valid),
    .rsp(biu_mem_rsp),
    .rsp_ready(biu_mem_rsp_ready),
    .*
  );

  itcm inst_itcm (
    .req_ready(o_iram_ready),
    .req_valid(o_iram_valid),
    .req(o_iram_req),
    .rsp(i_iram_rsp),
    .*
  );
  axi_uart inst_axi_uart(.*);
endmodule
